#include "windowRooms.h"
#include "windowInit.h"
#include "windowJuego.h"
#include "singleSocket.h"
#include <jsoncpp/json.h>
#include <sstream>
#include <unistd.h>
#include "user.h"

using std::vector;
using std::string;

windowRooms::windowRooms(sdlScreen& screen): window::window(screen){
	this->background.load("backgroundSalas.png");
	this->botBack.load("botonQuit.gif");
	this->sndBotClick.load("botClicked.wav");
	this->botNewSala.load("botonNewSala.gif");
	this->botNivel.load("botonPedirNivel.gif");
   	//this->botPlayersOrd.load("botonOrden.gif");
   	this->input.setColor(ColorTextImage::blanco);
   	this->input.setMaxLength(3);
   	this->input.setModoInput(numeros);
   	this->writing = false;
   	this->actualizarSalas();
   	this->maxPlyrsGetted = "";
   	this->nivelGetted = "";
   	this->waitingConf = false;

}

void destruirVector(vector<sdlButtonSala*>& v){
	for (vector<sdlButtonSala*>::iterator it = v.begin();it != v.end(); ++it){
		delete (*it);
	}
	v.clear();
}

void windowRooms::cargarSalas(){

	destruirVector(this->vBotsSalas);
	this->vSalas.clear();
	Json::Value salas;
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	socket->recibir(salas,user->getPass());
	unsigned cantDeSalas = salas.get("cantDeSalas",0).asUInt();
	for(unsigned i = 0; i < cantDeSalas; i++){
		std::stringstream s;
		s << "Sala " << i+1;
		Json::Value sala = salas.get(s.str(),0);

		unsigned nivel = sala.get("Nivel",0).asUInt();
		unsigned plyrsOnline = sala.get("CantJugadoresConectados",0).asUInt();
		unsigned maxPlayers = sala.get("MaximoJugadores",0).asUInt();
		Sala nuevaSala(i+1,nivel,plyrsOnline,maxPlayers);
		this->vSalas.push_back(nuevaSala);
		if (i < 7){
			sdlButtonSala* nuevoBotSala;
			nuevoBotSala = new sdlButtonSala(i+1,nivel,plyrsOnline,maxPlayers);
			nuevoBotSala->load("botonSala.gif");
			nuevoBotSala->renderizar();
			this->vBotsSalas.push_back(nuevoBotSala);
		}
	}
}

void windowRooms::show(){
	this->screen.applySurface(0,0,this->background);
	int actWidth = screen.width() - botBack.width();
	int actHeight = screen.height() - botBack.height();
	this->screen.applySurface(actWidth, actHeight, this->botBack);
	this->botBack.setPosition(actWidth,actHeight);
	actWidth = 310;
	actHeight = 15;
	this->screen.applySurface(actWidth, actHeight, this->botNewSala);
	this->botNewSala.setPosition(actWidth,actHeight);

	actWidth = 25;
	actHeight = 75;
	for (vector<sdlButtonSala*>::iterator it = vBotsSalas.begin();
	it != vBotsSalas.end(); ++it){
		(*it)->renderizar();
		this->screen.applySurface(actWidth, actHeight,(**it));
		(*it)->setPosition(actWidth,actHeight);
		actHeight += (*it)->height()+15;
	}
	if (this->waitingConf){
		sdlImage imgConfirm("confirmacion.png");
		actWidth = (this->screen.width() - imgConfirm.width())/2;
		actHeight = (this->screen.height() - imgConfirm.height())/2;
		this->screen.applySurface(actWidth,actHeight,imgConfirm);
	}

	this->screen.refresh();
}

void windowRooms::actualizarSalas(){
	Json::Value root;
	root["eleccion"] = "Actualizar salas";
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	socket->enviar(root,user->getPass());
	this->cargarSalas();
}

window* windowRooms::handleBotBack(){
	this->sndBotClick.play();
	SDL_Delay(100); //Le da tiempo para que se reproduzca el sonido
	User* user = User::getInstance();
	user->setShouldLog(false);
	singleSocket::eliminar();
	return new windowInit(this->screen);
}

void windowRooms::mostrarDialogo(){
	int actWidth = (this->screen.width() - this->botNivel.width())/2;
	int actHeight = (this->screen.height() - this->botNivel.height())/2;
	this->screen.applySurface(actWidth,actHeight,this->botNivel);
	this->botNivel.setPosition(actWidth,actHeight);
	actWidth+=(this->botNivel.width() - this->input.width())/2;
	actHeight+=75;
	this->screen.applySurface(actWidth,actHeight,this->input);
	this->screen.refresh();
}

void windowRooms::handleBotNewSala(){
	SDL_Event event;
	event.type=SDL_KEYDOWN;
	event.key.keysym.sym = SDLK_UNDERSCORE;
	this->input.resetText();
	this->input.handleEvent(event);
	this->writing = true;
	this->mostrarDialogo();
}

bool windowRooms::handleBotSala(unsigned numSala){
	Json::Value root;
	root["eleccion"] = "Seleccionar sala";
	root["Numero de sala"] = numSala;
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	socket->enviar(root,user->getPass());
	socket->recibir(root,user->getPass());
	string respuesta = root["Respuesta"].asString();
	if(respuesta == "Ingreso exitoso a sala"){
		return true;
	} else{
		sdlImage errorSala;
		if (respuesta == "Sala llena"){
			errorSala.load("salaLlena.png");
		} else {
			errorSala.load("nivelSalaAlto.png");
		}
		int actWidth = (this->screen.width() - errorSala.width())/2;
		int actHeight = (this->screen.height() - errorSala.height())/2;
		this->screen.applySurface(actWidth, actHeight, errorSala);
		this->screen.refresh();
		SDL_Delay(2000);
		this->show();
		return false;
	}
}

bool windowRooms::handleCrearSala(){
	Json::Value root;
	root["eleccion"] = "Crear sala"; //avisa que va a crear una sala nueva
	unsigned nivel = strtoul(this->nivelGetted.c_str(),NULL,10);
	root["Nivel"] = nivel;
	unsigned cantPlyrs = strtoul(this->maxPlyrsGetted.c_str(),NULL,10);
	root["Cantidad de jugadores"] = cantPlyrs;
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	socket->enviar(root,user->getPass());
	socket->recibir(root,user->getPass());
	if (root["Respuesta"] == "Ingreso exitoso a sala"){
		Sala nuevaSala(this->vSalas.size(),nivel,1,cantPlyrs);
		this->vSalas.push_back(nuevaSala);
		sdlButtonSala* nuevoBotSala;
		nuevoBotSala = new sdlButtonSala();
		nuevoBotSala->load("botonSala.gif");
		nuevoBotSala->setDatos(nuevaSala.getNumero(),nuevaSala.getNivel(),
			nuevaSala.getCantPlayers(),nuevaSala.getMaxPlayers());
		this->vBotsSalas.push_back(nuevoBotSala);
		return true;
	} else {
		this->show();
		this->writing = false;
		this->botNivel.load("botonPedirNivel.gif");
		this->nivelGetted = "";
		this->maxPlyrsGetted = "";
		sdlFont fuente("font.ttf", 24);
		sdlTextImage errorMsg;
		if (root["Respuesta"] == "Cantidad de jugadores erronea"){
			errorMsg.renderText(fuente,"CANTIDAD DE JUGADORES ERRONEA",ColorTextImage::amarillo);
		} else if (root["Respuesta"] == "Numero de nivel incorrecto"){
			errorMsg.renderText(fuente,"NUMERO DE NIVEL INCORRECTO",ColorTextImage::amarillo);
		} else {
			errorMsg.renderText(fuente,"HUBO UN ERROR AL CREAR LA SALA",ColorTextImage::amarillo);
		}
		int actWidth = (this->screen.width() - errorMsg.width())/2;
		int actHeight = (this->screen.height() - errorMsg.height())/2;
		this->screen.applySurface(actWidth,actHeight,errorMsg);
		this->screen.refresh();
		SDL_Delay(2500);
		this->show();
		return false;
	}
}

void mostrarEspera(sdlScreen& screen){
	sdlImage msjEspera("esperaSala.gif");
	int actWidth = (screen.width() - msjEspera.width())/2;
	int actHeight = (screen.height() - msjEspera.height())/2;
	screen.applySurface(actWidth,actHeight,msjEspera);
	screen.refresh();
}


void windowRooms::esperarCompleta(unsigned numSala){
	mostrarEspera(this->screen);
	Json::Value root;
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	string msj;
	do{
		socket->recibir(root,user->getPass());
		msj = root["Mensaje"].asString();
		unsigned nivel = root.get("Nivel",0).asUInt();
		unsigned maxJugadores = root.get("MaximoJugadores",0).asUInt();
		unsigned cantConectados = root.get("CantJugadoresConectados",0).asUInt();
		this->vSalas[numSala-1].setDatos(numSala, nivel,cantConectados,maxJugadores);
		this->vBotsSalas[numSala-1]->setDatos(numSala, nivel,cantConectados,maxJugadores);
		this->show();
		mostrarEspera(this->screen);
	}while(msj != "Sala completa");
}

void windowRooms::confirmar(){
	Json::Value root;
	std::string msj;
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	do{
		socket->recibir(root,user->getPass());
		msj = root["Mensaje"].asString();
	}while(msj != "Enviar confirmacion");//Le da pie para que pida la confirmacion al usuario
	this->waitingConf = true;
	this->show();
}

void windowRooms::handleY_NConfirm(bool b){
	singleSocket* socket = singleSocket::getInstance();
	User* user = User::getInstance();
	Json::Value rootConf;
	rootConf["Confirmacion"] = b;
	socket->enviar(rootConf,user->getPass());
}

bool windowRooms::handleEvent(const SDL_Event& event, window*& win){
	win = NULL;
	bool b = false; //Vale true si la venta entendió el evento
	if (event.type == SDL_MOUSEBUTTONDOWN && !this->waitingConf){
		if (event.button.button == SDL_BUTTON_LEFT){
			this->sndBotClick.play();
			if (this->botBack.wasClicked(event)){
				win = this->handleBotBack();
				b = true;
			} else if (this->botNewSala.wasClicked(event)){
				this->handleBotNewSala();
				b = true;
			} else{
				for (vector<sdlButtonSala*>::iterator it = vBotsSalas.begin();
				it != vBotsSalas.end(); ++it){
					if ((*it)->wasClicked(event)){
						if(this->handleBotSala((*it)->getNumSala())){
							this->esperarCompleta((*it)->getNumSala());
							this->confirmar();
							b = true;
							this->writing = false;
							//win = new windowJuego(this->screen);
						}
						break;
					}
				}
			}
			//SDL_Delay(150); // Vale la espera?
		}
	} else if (event.type == SDL_KEYDOWN){
		if (this->writing){
			this->input.handleEvent(event);
			this->mostrarDialogo();
			if (event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == SDLK_KP_ENTER){
				if (this->nivelGetted == ""){
					this->botNivel.load("botonPedirMaxPlayers.gif");
					this->nivelGetted = this->input.getTexto();
					this->handleBotNewSala();
				} else if (this->maxPlyrsGetted == ""){
					this->maxPlyrsGetted = this->input.getTexto();
					this->writing = false;
					if(this->handleCrearSala()){
						this->show();
						this->esperarCompleta(this->vSalas.size());
						this->confirmar();
						b = true;
						this->writing = false;
						this->nivelGetted = "";
						this->maxPlyrsGetted = "";
					}
				}
			}
		} else if (this->waitingConf){
			if (event.key.keysym.sym == SDLK_y){
				this->handleY_NConfirm(true);
				b = true;
				win = new windowJuego(this->screen);
			} else if (event.key.keysym.sym == SDLK_n){
				this->handleY_NConfirm(false);
				this->waitingConf = false;
				this->show();
				b = true;
			}
		} else {
			if (event.key.keysym.sym == SDLK_F5){
				this->actualizarSalas();
				this->show();
				b = true;
			}
		}
	}
	return b;
}

windowRooms::~windowRooms(){
	destruirVector(this->vBotsSalas);
}
